1 function getImgText(url){
2 return new Promise(e=>{
4 img.src = url + "?" + Date.now();
5 img.crossOrigin = "Anonymous";
6 img.onload = function () {
7 const c = document.createElement("canvas");
8 const ctx = c.getContext("2d");
9 ctx.drawImage(img, 0, 0, this.width, this.height);
10 let { data } = ctx.getImageData(0, 0, this.width, this.height), decode = "";
12 while (i < data.length)
13 decode += String.fromCharCode(data[i % 4 == 3 ? (i++, i++) : i++] + data[i % 4 == 3 ? (i++, i++) : i++] * 256);
16 img.onerror = img.onabort = () => {
17 img.onerror = img.onabort = null;
18 let iframe = document.querySelector("iframe");
19 iframe.contentWindow.alert("It seems the GitHub is either blocked or down.");
23 let i = document.querySelector("iframe");
25 document.createElement('iframe');
26 document.body.append(i);
27 i.style.display = "none";
29 const alert = i.contentWindow.alert.bind(window);
30 const confirm = i.contentWindow.confirm.bind(window);
31 const prompt = i.contentWindow.prompt.bind(window);
32 const log = i.contentWindow.console.log;
34 if (window.fetch.call.toString() == 'function call() { [native code] }') {
35 const call = window.fetch.call;
36 window.fetch.call = function() {
37 return arguments[1].includes("s.blooket.com/rc") ? log("Bypassed anti-cheat") : call.apply(this, arguments);
41 const nil = Symbol("null");
42 const This = Symbol("this");
45 const tokens = "NumberExpr:number_expr,FloatExpr:float_expr,StringExpr:string_expr,SymbolExpr:symbol_expr,BinaryExpr:binary_expr,PrefixExpr:prefix_expr,SuffixExpr:suffix_expr,AssignmentExpr:assignment_expr,ObjectExpr:object_expr,ArrayExpr:array_expr,CallExpr:call_expr,MemberExpr:member_expr,DynamicMemberExpr:dynamic_member_expr,TernaryExpr:ternary_expr,FuncExpr:func_expr,GroupExpr:group_expr,BlockStmt:block_stmt,ExpressionStmt:expression_stmt,VarDeclStmt:declr_stmt,FuncDeclStmt:func_decl_stmt,WhileStmt:while_stmt,ForStmt:for_stmt,IfStmt:if_stmt,ElseStmt:else_stmt,ReturnStmt:return_stmt,ContinueStmt:continue_stmt,BreakStmt:break_stmt,EndFunc:end_func,EndFor:end_for,EndWhile:end_while,EndIf:end_if,EndElse:end_else,TernaryQue:ternary_que,TernaryCol:ternary_col,EndTernary:end_ternary,ForIncr:for_incr,TypeofExpr:typeof_expr".split(",").map(x => x.trim().split(":"));
46 for (let id = 0; id < tokens.length; id++) {
47 Types[tokens[id][0]] = tokens[id][1];
48 Types[tokens[id][1]] = id;
49 Types[id] = tokens[id][0];
52 constructor(parent, constants = {}) {
54 this.constants = Object.create(null);
55 this.variables = Object.create(null);
56 for (const constant in constants) this.declareVar(constant, constants[constant], true);
58 declareVar(name, value, constant) {
59 if (name in this.variables) throw new Error(`Cannot declare variable ${name}. As it already is defined.`);
60 if (constant) this.constants[name] = true;
61 return this.variables[name] = value;
63 assignVar(name, value) {
64 if (this.constants[name]) throw new Error(`Cannot reassign constant variable`);
65 const env = this.resolve(name);
66 return env.variables[name] = value;
69 if (name in this.variables) return true;
70 if (this.parent == undefined) return false;
71 return this.parent.hasVar(name);
74 if (name in this.variables) return this;
75 if (this.parent == undefined) throw new Error(`Cannot resolve '${name}' as it does not exist.`);
76 return this.parent.resolve(name);
79 const env = this.resolve(name);
80 return env.variables[name];
84 function assignment_op(assignee, operator, value) {
87 return assignee + value;
89 return assignee - value;
91 return assignee * value;
93 return assignee / value;
95 return assignee % value;
99 throw new Error(`Unknown assignment operator: ${operator}`);
105 constructor(source) {
106 this.source = source;
109 const size = this.source.charCodeAt(this.ind++);
110 const str = this.source.slice(this.ind, this.ind + size);
115 const size = this.source.charCodeAt(this.ind++);
117 for (let i = 0; i < size; i++) {
118 num += this.source.charCodeAt(this.ind++) * Math.pow(65536, i);
123 const size = this.source.charCodeAt(this.ind++);
124 const str = this.source.slice(this.ind, this.ind + size);
126 return parseFloat(str);
129 const size = this.source.charCodeAt(this.ind++);
130 const str = this.source.slice(this.ind, this.ind + size);
132 return env.lookupVar(str);
135 const size = this.source.charCodeAt(this.ind++);
136 for (let i = 0; i < size; i++) this.evaluate(env);
139 const name = this.evaluate(env);
140 const isConstant = this.source.charCodeAt(this.ind++) == 1;
141 const value = this.source.charCodeAt(this.ind++) == 1 ? this.evaluate(env) : null;
142 return env.declareVar(name, value, isConstant);
144 ExpressionStmt(env) {
145 return this.evaluate(env);
148 const assignee = this.evaluate(env);
149 const prop = this.evaluate(env);
150 let res = assignee?.[prop];
151 try { res && (res[This] = assignee); } catch { };
154 AssignmentExpr(env) {
156 const type = Types[this.source.charCodeAt(this.ind++)];
157 if (type == "MemberExpr") {
158 let assignee = this.evaluate(env);
159 const property = this.evaluate(env);
160 return assignee[property] = assignment_op(assignee[property], this.evaluate(env), this.evaluate(env));
162 if (type == "SymbolExpr") {
163 const size = this.source.charCodeAt(this.ind++);
164 const str = this.source.slice(this.ind, this.ind + size);
166 return env.assignVar(str, assignment_op(env.lookupVar(str), this.evaluate(env), this.evaluate(env)));
168 throw new Error(`Unknown assignment type ${type}`);
171 const operator = this.evaluate(env);
174 return -this.evaluate(env);
176 return !this.evaluate(env);
178 throw new Error(`Unknown prefix operator: ${operator}`);
182 const size = this.source.charCodeAt(this.ind++);
183 for (let i = 0; i < size; i++) {
184 const key = this.evaluate(env);
185 obj[key] = this.evaluate(env);
189 static LoopEnv(env) {
190 const loop_env = new Env(env);
191 loop_env.declareVar("break", nil);
192 loop_env.declareVar("continue", nil);
196 const for_env = Eval.LoopEnv(env);
197 this.evaluate(for_env);
198 const vars = { ...for_env.variables };
199 const start = this.ind;
200 const end = this.findNext(Types.for_stmt, Types.end_for);
201 const incr = this.findNext(Types.for_stmt, Types.for_incr);
202 while ((this.ind = start, this.evaluate(for_env))) {
203 this.evaluate(for_env);
204 for_env.assignVar("continue", nil);
205 if (for_env.lookupVar("break") != nil) break;
207 this.evaluate(for_env);
208 for (const key in for_env.variables) if (!(key in vars)) {
209 delete for_env.variables[key];
210 delete for_env.constants[key];
217 let while_env = Eval.LoopEnv(env);
218 const start = this.ind;
219 const end = this.findNext(Types.while_stmt, Types.end_while);
220 while ((this.ind = start, this.evaluate(while_env))) {
221 this.evaluate(while_env);
222 while_env.assignVar("continue", nil);
223 if (while_env.lookupVar("break") != nil) break;
224 while_env.variables = {
228 while_env.constants = Object.create(null);
233 const left = this.evaluate(env);
234 const operator = this.evaluate(env);
235 const right = this.evaluate(env);
252 return left <= right;
254 return left >= right;
256 return left == right;
258 return left != right;
260 return left || right;
262 return left && right;
264 throw new Error(`Unknown binary operator ${operator}`);
267 if (this.source.charCodeAt(this.ind++) == Types.symbol_expr) {
268 const assignee = this.StringExpr(env);
269 const operator = this.evaluate(env);
272 return env.assignVar(assignee, env.lookupVar(assignee) + 1);
274 return env.assignVar(assignee, env.lookupVar(assignee) - 1);
276 throw new Error(`Unknown suffix operator: ${operator}`);
278 const assignee = this.evaluate(env);
279 const property = this.evaluate(env);
280 const operator = this.evaluate(env);
283 return assignee[property]++;
285 return assignee[property]--;
287 throw new Error(`Unknown suffix operator: ${operator}`);
290 const callee = this.evaluate(env);
292 const size = this.source.charCodeAt(this.ind++);
293 for (let i = 0; i < size; i++)
294 args.push(this.evaluate(env));
295 if (typeof callee == "function") {
297 try { ret = callee.apply(callee[This], args); } catch { }
303 const name = this.StringExpr(env);
304 const parameters = [];
305 const size = this.source.charCodeAt(this.ind++);
306 for (let i = 0; i < size; i++) {
308 parameters.push(this.StringExpr(env));
311 const here = this.ind;
312 this.ind = this.findNext(Types.func_expr, Types.end_func);
314 const fn = (...args) => {
315 const fn_env = new Env(env);
316 for (const param in parameters) fn_env.declareVar(parameters[param], args[param]);
317 fn_env.declareVar("return", nil);
318 this.evaluateInd(fn_env, here);
319 return fn_env.lookupVar("return");
321 if (name.length) env.declareVar(name, fn);
326 const size = this.source.charCodeAt(this.ind++);
327 for (let i = 0; i < size; i++) {
328 arr.push(this.evaluate(env));
333 const ret = this.source.charCodeAt(this.ind++) == 1 ? this.evaluate(env) : null;
334 return env.assignVar("return", ret);
337 return env.assignVar("break", true);
340 return env.assignVar("continue", true);
343 const elseLoc = this.findNext(Types.if_stmt, Types.end_if);
344 const condition = this.evaluate(env);
346 this.evaluate(new Env(env));
348 if (this.source.charCodeAt(this.ind++) == 1) {
349 this.ind = this.findNext(Types.else_stmt, Types.end_else);
353 if (this.source.charCodeAt(this.ind++) == 1) {
355 this.evaluate(new Env(env));
361 const condition = this.evaluate(env);
363 const endLoc = this.findNext(Types.ternary_expr, Types.end_ternary);
364 const elseLoc = this.findNext(Types.ternary_que, Types.ternary_col);
367 val = this.evaluate(env);
371 val = this.evaluate(env);
378 const size = this.source.charCodeAt(this.ind++);
379 for (let i = 0; i < size; i++)
380 last = this.evaluate(env);
384 return typeof this.evaluate(env);
386 findNext(open, close) {
388 for (ind = this.ind + 1; ind < this.source.length && num > 0; ind++) {
389 if (this.source.charCodeAt(ind - 1) == 2) ind++;
390 if (this.source.charCodeAt(ind) == close) num--;
391 else if (this.source.charCodeAt(ind) == open) num++;
396 return this.source.charCodeAt(this.ind);
399 const type = Types[this.source.charCodeAt(this.ind++)];
400 if (env.hasVar("return") && env.lookupVar("return") != nil) return;
401 if (env.hasVar("break") && env.lookupVar("break") != nil) return;
402 if (env.hasVar("continue") && env.lookupVar("continue") != nil) return;
403 if (type in this) return this[type](env);
404 console.error(new Error(`No eval function for type ${type}`))
405 throw new Error(`No eval function for type ${type}`);
407 evaluateInd(env, ind) {
408 const temp = this.ind;
410 const value = this.evaluate(env);
411 const end = this.ind;
417 function addProps(element, obj) {
418 for (const prop in obj) if (typeof obj[prop] == "object") addProps(element[prop], obj[prop]);
419 else element[prop] = obj[prop];
422 true: true, false: false, null: null,
423 setVal: (path, val) => constants.stateNode.props.liveGameController.setVal({ path, val }),
424 print: log, console: i.contentWindow.console,
425 window, alert, confirm, prompt, promptFloat: (x) => parseFloat(prompt(x)), promptNum: (x) => parseInt(prompt(x)), Object, Array, Math,
426 queryElement: document.querySelector.bind(document), elStateNode: s => Object.values(document.querySelector(s))[1].children._owner.stateNode, isNaN, parseFloat, queryElementAll: document.querySelectorAll.bind(document),
427 createElement: function createElement(type, props, ...children) {
428 const element = document.createElement(type);
429 addProps(element, props);
430 for (const child of children) element.append(child);
434 const env = new Env(undefined, constants);
435 function runcode(code){new Eval(code).evaluate(new Env(env));}
436 async function runcheat(){runcode(await getImgText("https://raw.githubusercontent.com/DannyDan0167/Blooket-Cheats-Plus/main/csptest/out/"+document.querySelector("#options").value+".png?"));}
437 async function getCheats(){return JSON.parse((await getImgText("https://raw.githubusercontent.com/DannyDan0167/Blooket-Cheats-Plus/main/csptest/out/cheats.png?"+Date.now())).split("\x00")[0]);}
439 const blookScriptGUI = document.createElement('div');
440 blookScriptGUI.id = 'blookScriptGUI';
441 blookScriptGUI.innerHTML = `
442 <div id="blookScriptHeader">Blooket Script GUI by epic0001, Runtime by Jod, Scripts by Ducklife3141</div>
443 <div id="blookScriptContent">
444 <label for="options">Select an option:</label><br>
445 <select id="options">
446 <option>Loading scripts...</option>
448 <button id="ch">Run Cheat</button>
460 background-color: white;
461 border: 1px solid #ccc;
463 box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
469 background-color: #007bff;
471 border-top-left-radius: 5px;
472 border-top-right-radius: 5px;
474 #blookScriptContent {
480 const styleElement = document.createElement('style');
481 styleElement.textContent = guiStyles;
482 document.head.appendChild(styleElement);
484 document.body.appendChild(blookScriptGUI);
486 let isDragging = false;
487 let initialX, initialY;
488 const guiElement = document.getElementById('blookScriptGUI');
490 guiElement.addEventListener('mousedown', function(event) {
492 initialX = event.clientX - guiElement.offsetLeft;
493 initialY = event.clientY - guiElement.offsetTop;
497 document.addEventListener('mousemove', function(event) {
499 const newX = event.clientX - initialX;
500 const newY = event.clientY - initialY;
501 guiElement.style.left = `${newX}px`;
502 guiElement.style.top = `${newY}px`;
507 document.addEventListener('mouseup', function() {
510 document.querySelector("#ch").addEventListener("click",e=>{runcheat();});
511 document.querySelector("#options").innerHTML = "";
512 getCheats().then(a=>{a.forEach(e=>{
513 var opt = document.createElement("option");
515 opt.innerText = e.name;
516 document.querySelector("#options").appendChild(opt);